# 装饰器
# decorator就是一个返回函数的高阶函数
# 两层装饰器
def log(func):
    def wrapper(*args, **kw):
        print('call %s():' % func.__name__)
        return func(*args, **kw)
    return wrapper

@log
def now():
    print('2015-3-25')
# @log 相当于执行了 now = log(now)

# 三次装饰器
# def log2(text):
#     def decorator(func):
#         @functools.wraps(func)
#         def wrapper(*args, **kw):
#             print('%s %s():' % (text, func.__name__))
#             return func(*args, **kw)
#         return wrapper
#     return decorator
# @log('execute')
# def now2():
#     print('2015-3-25')
# @log('execute')相当于执行了  now2 = log2('execute')(now2)

# 练习
# 请设计一个decorator，它可作用于任何函数上，并打印该函数的执行时间
import time, functools
def metric(fn):
    @functools.wraps(fn)
    def wrapper(*args, **kw):
        start = int(time.time() * 1000)
        var = fn(*args,**kw)
        end = int(time.time() * 1000)
        print('%s executed in %s ms' % (fn.__name__, end-start))
        return var
    return wrapper

# 测试
@metric
def fast(x, y):
    time.sleep(0.0012)
    return x + y

@metric
def slow(x, y, z):
    time.sleep(0.1234)
    return x * y * z

f = fast(11, 22)
s = slow(11, 22, 33)
print(f)
print(s)
if f != 33:
    print('测试失败!')
elif s != 7986:
    print('测试失败!')
